package Underworld_Survival;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 通用权重随机选择器（支持不同时期的不同概率和选择数量）
 * @param <T> 元素类型（如String表示事件/商品名称）
 */
class WeightedRandomSelector<T> {
    private final Random random = new Random();

    /**
     * 根据配置生成随机结果
     * @param config 时期配置
     * @return 随机选择的元素列表（不重复）
     */
    public List<T> select(PeriodConfig<? extends T> config) {
        List<WeightedItem<? extends T>> remaining = new ArrayList<>(config.getWeightedItem());
        List<T> selected = new ArrayList<>();

        // 确定本次要选择的数量（在min和max之间随机）
        int selectCount = config.getMinSelect() +
                random.nextInt(config.getMaxSelect() - config.getMinSelect() + 1);

        for (int i = 0; i < selectCount; i++) {
            // 计算总权重
            double totalWeight = remaining.stream()
                    .mapToDouble(WeightedItem::getWeight)
                    .sum();

            if (totalWeight <= 0) throw new IllegalStateException("总权重必须大于0");

            // 生成随机数并选择
            double randomPoint = random.nextDouble() * totalWeight;
            int selectedIndex = findSelectedIndex(remaining, randomPoint);

            // 记录结果并移除已选项
            selected.add(remaining.get(selectedIndex).getItem());
            remaining.remove(selectedIndex);
        }
        return selected;
    }

    /**
     * 根据当前概率分布查找命中元素的索引
     */
    private int findSelectedIndex(List<WeightedItem<? extends T>> items, double target) {
        double accumulated = 0.0;
        for (int i = 0; i < items.size(); i++) {
            accumulated += items.get(i).getWeight();
            if (accumulated >= target) {
                return i;
            }
        }
        return items.size() - 1; // 处理浮点误差
    }
}
